home *** CD-ROM | disk | FTP | other *** search
/ Pocket PC Game Programming / Pocket PC Game Programming.iso / source.exe / CH15 / GameLibrary / CBitmap.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-30  |  8.8 KB  |  364 lines

  1. //////////////////////////////////////////////////////////////////////
  2. // Pocket PC Game Programming
  3. // Chapter 9: Sprites and Animation
  4. //
  5. // CBitmap Source File
  6. //
  7. // This file includes the CBitmap class implementation.
  8. //
  9. //////////////////////////////////////////////////////////////////////
  10.  
  11. #include "stdafx.h"
  12. #include "CBitmap.h"
  13.  
  14. //////////////////////////////////////////////////////////////////////
  15. // CBitmap Constructor
  16. //
  17. // This function is called when the class is instantiated.
  18. //
  19.  
  20. CBitmap::CBitmap(HDC hdc)
  21. {
  22.     hScreenDC = hdc;
  23. }
  24.  
  25. //////////////////////////////////////////////////////////////////////
  26. // CBitmap Destructor
  27. //
  28. // This function is called when the class is terminated.
  29. //
  30. CBitmap::~CBitmap()
  31. {
  32.     if (lpDIB != NULL)
  33.         free(lpDIB);
  34.  
  35.     if (hSourceDC != NULL) 
  36.     {
  37.         SelectObject(hSourceDC, hOldBitmap);
  38.         DeleteObject(hOldBitmap);
  39.         DeleteDC(hSourceDC);
  40.     }
  41. }
  42.  
  43. //////////////////////////////////////////////////////////////////////
  44. // CBitmap::Create
  45. //
  46. // Used to create a new memory device context.
  47. //
  48. BOOL CBitmap::Create(int Width, int Height)
  49. {
  50.     HBITMAP hSourceBitmap;
  51.  
  52.     hSourceDC = CreateCompatibleDC(GetScreenDC());
  53.     if (hSourceDC == NULL)
  54.         return FALSE;
  55.  
  56.     hSourceBitmap = CreateCompatibleBitmap(GetScreenDC(), Width, Height);
  57.     if (hSourceBitmap == NULL)
  58.         return FALSE;
  59.  
  60.     hOldBitmap = SelectBitmap(hSourceDC, hSourceBitmap);
  61.     if (hOldBitmap == NULL)
  62.         return FALSE;
  63.  
  64.     DeleteObject(hSourceBitmap);
  65.     return TRUE;
  66. }
  67.  
  68. //////////////////////////////////////////////////////////////////////
  69. // CBitmap::Load
  70. //
  71. // Loads a bitmap file into a device context.
  72. //
  73. BOOL CBitmap::Load(LPTSTR lpFilename)
  74. {
  75.     LPBYTE lpSourceBits;
  76.     HBITMAP hSourceBitmap;
  77.     DWORD dwSourceBitsSize;
  78.     LPBITMAPINFO lpSrcDIB;
  79.  
  80.     SetFilename(lpFilename);
  81.     if (!LoadDIB(lpFilename))
  82.         return FALSE;
  83.  
  84.     lpSrcDIB = (LPBITMAPINFO)lpDIB;
  85.  
  86.     hSourceBitmap = CreateDIBSection(GetScreenDC(), lpSrcDIB, DIB_RGB_COLORS,
  87.         (void **)&lpSourceBits, NULL, 0);
  88.  
  89.     //hSourceDC = CreateCompatibleDC(GetDC(NULL));
  90.     hSourceDC = CreateCompatibleDC(GetScreenDC());
  91.     dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * 
  92.         BytesPerLine(&(lpSrcDIB->bmiHeader));
  93.     memcpy(lpSourceBits, BitmapDataIndex((LPSTR)lpSrcDIB), dwSourceBitsSize);
  94.  
  95.     SelectObject(hSourceDC, hSourceBitmap);
  96.  
  97.     //store bitmap header into bmBitmap
  98.     GetObject(hSourceBitmap, sizeof(BITMAP), &bmBitmap);
  99.  
  100.     DeleteObject(hSourceBitmap);
  101.  
  102.     return TRUE;
  103. }
  104.  
  105. //////////////////////////////////////////////////////////////////////
  106. // CBitmap::LoadDIB
  107. //
  108. // Reads a bitmap from disk and converts it to a DIB buffer.
  109. //
  110. BOOL CBitmap::LoadDIB(LPCTSTR szFileName)
  111. {
  112.     HANDLE hFile;
  113.     BITMAPFILEHEADER bfh;
  114.     LPBYTE lpTemp = NULL;
  115.     WORD wPaletteSize = 0;
  116.     DWORD dwBitsSize = 0;
  117.     BOOL bRet;
  118.  
  119.     //open the file
  120.     hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  121.         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  122.     if (hFile == INVALID_HANDLE_VALUE)
  123.     {
  124.         return FALSE;
  125.     }
  126.  
  127.     //read the header
  128.     bRet = ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwImageSize, NULL);
  129.     if ((bRet == FALSE) || (dwImageSize != sizeof(BITMAPFILEHEADER)))
  130.     {
  131.         CloseHandle(hFile);
  132.         return FALSE;
  133.     }
  134.  
  135.     //is this a valid bitmap file?
  136.     if ((bfh.bfType != 0x4d42) || (bfh.bfReserved1 != 0) || (bfh.bfReserved2 != 0))
  137.     {
  138.         CloseHandle(hFile);
  139.         return FALSE;
  140.     }
  141.  
  142.     //allocate memory for the bitmap data
  143.     lpDIB = (LPBYTE) malloc(sizeof(BITMAPINFO));
  144.     if (lpDIB == NULL)
  145.     {
  146.         CloseHandle(hFile);
  147.         return FALSE;
  148.     }
  149.  
  150.     //read in the BITMAPINFOHEADER
  151.     bRet = ReadFile(hFile, lpDIB, sizeof(BITMAPINFOHEADER), &dwImageSize, NULL);
  152.     if ((bRet == FALSE) || (dwImageSize != sizeof(BITMAPINFOHEADER)))
  153.     {
  154.         CloseHandle(hFile);
  155.         free(lpDIB);
  156.         return FALSE;
  157.     }
  158.  
  159.     if (((LPBITMAPINFOHEADER)lpDIB)->biSize != sizeof(BITMAPINFOHEADER))
  160.     {
  161.         CloseHandle(hFile);
  162.         free(lpDIB);
  163.         return FALSE;
  164.     }
  165.  
  166.     wPaletteSize = PaletteSize((LPSTR)lpDIB);
  167.     dwBitsSize = ImageHeight() * BytesPerLine((LPBITMAPINFOHEADER) lpDIB);
  168.  
  169.     //realloc the DIB buffer
  170.     lpTemp = (LPBYTE) realloc(lpDIB, sizeof(BITMAPINFOHEADER) + wPaletteSize + dwBitsSize);
  171.     if (lpTemp == NULL)
  172.     {
  173.         CloseHandle(hFile);
  174.         free(lpDIB);
  175.         return FALSE;
  176.     }
  177.  
  178.     lpDIB = lpTemp;
  179.  
  180.     //read palette if one is present
  181.     if (wPaletteSize > 0)
  182.     {
  183.         bRet = ReadFile(hFile, ((LPBITMAPINFO)lpDIB)->bmiColors, wPaletteSize, &dwImageSize, NULL);
  184.         if ((bRet == FALSE) || (dwImageSize != wPaletteSize))
  185.         {
  186.             CloseHandle(hFile);
  187.             free(lpDIB);
  188.             return FALSE;
  189.         }
  190.     }
  191.  
  192.     if (bfh.bfOffBits > 0)
  193.     {
  194.         if (SetFilePointer(hFile, bfh.bfOffBits, NULL, FILE_BEGIN) == 0xffffffff)
  195.         {
  196.             CloseHandle(hFile);
  197.             free(lpDIB);
  198.             return FALSE;
  199.         }
  200.     }
  201.  
  202.     //read the image data
  203.     bRet = ReadFile(hFile, BitmapDataIndex((LPSTR)lpDIB), dwBitsSize, &dwImageSize, NULL);
  204.     if ((bRet == FALSE) || (dwImageSize != dwBitsSize))
  205.     {
  206.         CloseHandle(hFile);
  207.         free(lpDIB);
  208.         return FALSE;
  209.     }
  210.  
  211.     //close file and return
  212.     CloseHandle(hFile);
  213.     return TRUE;
  214. }
  215.  
  216.  
  217. //////////////////////////////////////////////////////////////////////
  218. // CBitmap::BitBlit
  219. //
  220. // Blits a bitmap to the default device context.
  221. //
  222. BOOL CBitmap::BitBlit(int x, int y)
  223. {
  224.     return BitBlt(GetScreenDC(), x, y, ImageWidth(), ImageHeight(), hSourceDC, 0, 0, SRCCOPY);
  225. }
  226.  
  227.  
  228. //////////////////////////////////////////////////////////////////////
  229. // CBitmap::BitBlit (Overloaded)
  230. //
  231. // Blits a bitmap to a destination device context.
  232. //
  233. BOOL CBitmap::BitBlit(HDC hdc, int x, int y)
  234. {
  235.     return BitBlt(hdc, x, y, ImageWidth(), ImageHeight(), hSourceDC, 0, 0, SRCCOPY);
  236. }
  237.  
  238.  
  239. //////////////////////////////////////////////////////////////////////
  240. // CBitmap::TransBlit
  241. //
  242. // Blits a transparent bitmap to the default device context.
  243. //
  244. BOOL CBitmap::TransBlit(int x, int y, COLORREF clrTrans)
  245. {
  246.     return TransparentImage(GetScreenDC(), x, y, ImageWidth(), ImageHeight(), hSourceDC, 0, 0, 
  247.                 ImageWidth(), ImageHeight(), clrTrans);
  248. }
  249.  
  250.  
  251. //////////////////////////////////////////////////////////////////////
  252. // CBitmap::StretchBlit
  253. //
  254. // Blits a scaled bitmap to the default device context.
  255. //
  256. BOOL CBitmap::StretchBlit(int x, int y, int dx, int dy)
  257. {
  258.     return StretchBlt(GetScreenDC(), x, y, dx, dy, hSourceDC, 0, 0, ImageWidth(), ImageHeight(), SRCCOPY);
  259. }
  260.  
  261. //////////////////////////////////////////////////////////////////////
  262. // CBitmap::BitmapDataIndex
  263. //
  264. // Locate image bits and return a pointer to the memory block
  265. //
  266. LPSTR CBitmap::BitmapDataIndex(LPSTR lpbi)
  267. {
  268.     return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi));
  269. }
  270.  
  271. //////////////////////////////////////////////////////////////////////
  272. // CBitmap::PaletteSize
  273. //
  274. // Return the byte size of the color table.
  275. //
  276. int CBitmap::PaletteSize(LPSTR lpbi)
  277. {
  278.     int iNumColors;
  279.     DWORD dwClrUsed;
  280.  
  281.     dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;
  282.     if (dwClrUsed)
  283.     {
  284.         iNumColors = (WORD)dwClrUsed;
  285.     }
  286.     else
  287.     {
  288.         //only applicable to 8-bit or less bit depth
  289.         switch (BitCount())
  290.         {
  291.             case 1: 
  292.                 iNumColors = 2;
  293.                 break;
  294.  
  295.             case 2: 
  296.                 iNumColors = 4;
  297.                 break;
  298.  
  299.             case 4: 
  300.                 iNumColors = 16;
  301.                 break;
  302.  
  303.             case 8: 
  304.                 iNumColors = 256;
  305.                 break;
  306.  
  307.             default: 
  308.                 iNumColors = 0;
  309.         }
  310.     }
  311.  
  312.     return (iNumColors * sizeof(RGBQUAD));
  313. }
  314.  
  315. //////////////////////////////////////////////////////////////////////
  316. // CBitmap::BytesPerLine
  317. //
  318. // Returns the number of bytes in one scan line of the bitmap.
  319. //
  320. int CBitmap::BytesPerLine(LPBITMAPINFOHEADER lpBMIH)
  321. {
  322.     return (int)(((ImageWidth() * NumPlanes() * BitCount() + 31) / 32) * 4);
  323. }
  324.  
  325. //////////////////////////////////////////////////////////////////////
  326. // CBitmap::BitCount
  327. //
  328. // Returns the bit count (color depth) of the bitmap.
  329. //
  330. int CBitmap::BitCount()
  331. {
  332.     return (int)((LPBITMAPINFOHEADER) lpDIB)->biBitCount;
  333. }
  334.  
  335. //////////////////////////////////////////////////////////////////////
  336. // CBitmap::ImageWidth
  337. //
  338. // Returns the horizontal resolution of the bitmap.
  339. //
  340. int CBitmap::ImageWidth()
  341. {
  342.     return (int)((LPBITMAPINFOHEADER) lpDIB)->biWidth;
  343. }
  344.  
  345. //////////////////////////////////////////////////////////////////////
  346. // CBitmap::ImageHeight
  347. //
  348. // Returns the vertical resolution of the bitmap.
  349. //
  350. int CBitmap::ImageHeight()
  351. {
  352.     return (int)((LPBITMAPINFOHEADER) lpDIB)->biHeight;
  353. }
  354.  
  355. //////////////////////////////////////////////////////////////////////
  356. // CBitmap::NumPlanes
  357. //
  358. // Returns the number of color planes in the bitmap.
  359. //
  360. int CBitmap::NumPlanes()
  361. {
  362.     return (int)((LPBITMAPINFOHEADER) lpDIB)->biPlanes;
  363. }
  364.